%%%-------------------------------------------------------------------
%%% @author liuwentao
%%% @doc
%%%     通知模块
%%% @end
%%% Created : 19. 7月 2021 19:57
%%%-------------------------------------------------------------------
-module(notice).
-author("liuwentao").

-export([
    format/2
    , quality_name/1
    , send/3
    , send/4
    , gain_item/2
    , gain_item/3
    , replace_role/2
    , replace_msg/2
    , merge_msg/2
    , merge_title_tail/3
]).


-include("notice.hrl").
-include("role.hrl").
-include("common.hrl").
-include("item.hrl").
-include("protocol.hrl").
-include("package.hrl").

%%--------------------------------------------------------------------
%%  APIs
%%--------------------------------------------------------------------
%% @doc 根据品质取名称
-spec quality_name(0..4) -> bitstring().
quality_name(?quality_green) -> ?T("绿");
quality_name(?quality_blue) -> ?T("蓝");
quality_name(?quality_purple) -> ?T("紫");
quality_name(?quality_orange) -> ?T("橙");
quality_name(_) -> ?T("白").

%%--------------------------------------------------------------------
%% @doc 广播
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
%% @doc
%% 发送指定样式的消息给玩家
%% Example:
%%   1: 直接发送语句
%%   send(Role, ?notice_up, ?T("你的余额不足,请充值"))
%%   2: 附带组装的发送
%%   send(Role, ?notice_up, {?T("您不足~w个~w，无法进行~ts"), [{item_2, 20000}, {string_1, 5}, {string_1, "锻造"}]})
%%   3: 先组装再发送
%%   Msg = format(?T("您不足~w个~w，无法进行~ts"), [{item_2, 20000}, {string_1, 5}, {string_1, "锻造"}]),
%%   send(Role, ?notice_up, Msg).
%% @end
%%--------------------------------------------------------------------
send(To, Style, {F, A}) ->
    send(To, Style, format(F, A), []);
send(To, Style, Msg) when is_list(Msg) ->
    send(To, Style, Msg, []).

send(_To, _Style, "", _Limit) -> ok;
send(Role = #role{}, Style, Msg, Limit) ->
    role:link_send(Role, 9902, {Style, Msg, Limit}),
    ok;
send(RoleId = {_, _, _}, Style, Msg, Limit) ->
    role:pack_send(RoleId, 9902, {Style, Msg, Limit}),
    ok;
send({conn_pid, ConnPid}, Style, Msg, Limit) ->
    server_conn:pack_send(ConnPid, 9902, {Style, Msg, Limit}),
    ok;
send(conn_pid, Style, Msg, Limit) ->
    case get(conn_pid) of
        ConnPid when is_pid(ConnPid) ->
            server_conn:pack_send(ConnPid, 9902, {Style, Msg, Limit}),
            ok;
        _ -> ok
    end;
send({pid, Pid}, Style, Msg, Limit) when is_pid(Pid) ->
    role:pack_send(Pid, 9902, {Style, Msg, Limit}),
    ok;
send(_, _, _, _) -> ok.


%% @doc 合并字符串
merge_msg("", Msg2) -> Msg2;
merge_msg(Msg1, "") -> Msg1;
merge_msg(Msg1, Msg2) -> util:flist("~ts，~ts", [Msg1, Msg2]).

%% @doc 消息合并上头部跟尾部
merge_title_tail("", _Title, _Tail) -> "";%% 如果信息主体是空的,不需要提示
merge_title_tail(Msg, "", "") -> Msg;
merge_title_tail(Msg, Title, "") -> util:flist("~ts，~ts", [Title, Msg]);
merge_title_tail(Msg, "", Tail) -> util:flist("~ts，~ts", [Msg, Tail]);
merge_title_tail(Msg, Title, Tail) -> util:flist("~ts，~ts，~ts", [Title, Msg, Tail]).


%% @doc 替换角色信息
-spec replace_role(bitstring(), list() | bitstring()) -> bitstring().
replace_role(Msg, RoleInfo) ->
    replace_msg([{"#role#", RoleInfo}], Msg).

%% @doc 信息替换
replace_msg([], Msg) ->
    Msg;
replace_msg([{ReStr, L = [_ | _]} | T], Msg) ->
    Str = notice:format("~ts", L),
    NewMsg = re:replace(Msg, ReStr, Str, [{return, list}, unicode]),
    replace_msg(T, NewMsg);
replace_msg([{ReStr, Str} | T], Msg) ->
    NewMsg = re:replace(Msg, ReStr, Str, [{return, list}, unicode]),
    replace_msg(T, NewMsg).

%%--------------------------------------------------------------------
%% @doc 消息提示格式化函数
%% 模拟io:format/1,2函数的使用方式，但只支持格式控制符~w、~ts
%% Example:
%% @todo 使用中
%%-- <li> {string_1|颜色值} 以指定颜色显示整个文本</li>
%%-- <li> {string_2|颜色值|字符内容} 以指定颜色显示字符串</li>
%%-- <li> {string_3|品质|字符内容} 以指定品质显示字符串</li>
%%-- <li> {face_1|ID} 显示一个表情</li>
%%-- <li> {role_1|颜色值} 以指定颜色显示主角名字</li>
%%-- <li> {role_2|角色名} 使用默认颜色显示一个角色名</li>
%%-- <li> {role_2|角色名|颜色} 使用指定颜色显示一个角色名</li>
%%--------------------------------------------------------------------

format(Format, Args) -> util:flist(Format, do_format(Args, [])).
do_format([], Rtn) -> lists:reverse(Rtn);
do_format([Val | T], Rtn) when is_integer(Val) ->
    do_format(T, [Val | Rtn]);
do_format([{color_1, Color} | T], Rtn) ->
    R = ?S("{color_1|~w}", [Color]),
    do_format(T, [R | Rtn]);
do_format([{string_1, Color} | T], Rtn) when is_integer(Color) ->
    R = ?S("{string_1|~w}", [Color]),
    do_format(T, [R | Rtn]);
do_format([{string_1, Str} | T], Rtn) ->
    R = ?S("~ts", [Str]),
    do_format(T, [R | Rtn]);
do_format([{string_2, Color, Str} | T], Rtn) ->
    R = ?S("{string_2|~w|~ts}", [Color, util:to_list(Str)]),
    do_format(T, [R | Rtn]);
do_format([{string_3, Quality, Str} | T], Rtn) ->
    R = ?S("{string_3|~w|~ts}", [Quality, util:to_list(Str)]),
    do_format(T, [R | Rtn]);
do_format([{link_1, Color, Content, Source} | T], Rtn) ->
    R = ?S("{link_1|~w|~ts|~w}", [Color, Content, Source]),
    do_format(T, [R | Rtn]);
do_format([{link_1, Link} | T], Rtn) ->
    R = ?S("{link_1|~ts}", [Link]),
    do_format(T, [R | Rtn]);
do_format([{link_2, Link, Str} | T], Rtn) ->
    R = ?S("{link_2|~ts|~ts}", [Link, Str]),
    do_format(T, [R | Rtn]);
do_format([{role_1, #role{id = {Rid, Platform, ZoneId}, name = Name}} | T], Rtn) ->
    R = ?S("{role_1|~w|~ts|~w|~ts}", [Rid, Platform, ZoneId, Name]),
    do_format(T, [R | Rtn]);
do_format([{role_1, {Rid, Platform, ZoneId}, Name} | T], Rtn) ->
    R = ?S("{role_1|~w|~ts|~w|~ts}", [Rid, Platform, ZoneId, Name]),
    do_format(T, [R | Rtn]);
do_format([{role_1, {{Rid, Platform, ZoneId}, Name}} | T], Rtn) ->
    R = ?S("{role_1|~w|~ts|~w|~ts}", [Rid, Platform, ZoneId, Name]),
    do_format(T, [R | Rtn]);
do_format([{role_1, RoleList} | T], Rtn) ->
    NewT = [do_format([{role_1, R}], []) || R <- RoleList],
    Str = string:join(NewT, ","),
    do_format(T, [Str | Rtn]);
do_format([{role_2, RoleName} | T], Rtn) when is_list(RoleName) ->
    R = ?S("{role_2|~ts}", [RoleName]),
    do_format(T, [R | Rtn]);
do_format([{role_2, RoleName, Color} | T], Rtn) when is_list(RoleName) ->
    R = ?S("{role_2|~ts|~w}", [RoleName, Color]),
    do_format(T, [R | Rtn]);
do_format([{role_2, #role{name = RoleName}} | T], Rtn) when is_list(RoleName) ->
    R = ?S("{role_2|~ts}", [RoleName]),
    do_format(T, [R | Rtn]);
do_format([{role_2, #role{name = RoleName}, Color} | T], Rtn) when is_list(RoleName) ->
    R = ?S("{role_2|~ts|~w}", [RoleName, Color]),
    do_format(T, [R | Rtn]);
do_format([{role_3, {Rid, Platform, ZoneId}, Name} | T], Rtn) ->
    R = ?S("{role_3|~w|~ts|~w|~ts}", [Rid, Platform, ZoneId, Name]),
    do_format(T, [R | Rtn]);
do_format([{face_1, FaceId} | T], Rtn) ->
    R = ?S("{face_1|~w}", [FaceId]),
    do_format(T, [R | Rtn]);
do_format([H | T], Rtn) when is_list(H) ->
    do_format(T, [H | Rtn]);
do_format([H | T], Rtn) ->
    ?ERR("对消息内容进行格式化处理时，发现无法识别的格式: ~w From:~w", [H, util:get_stacktrace()]),
    do_format(T, ["  " | Rtn]).

%% @doc 推送获取物品效果
gain_item(Role, L) ->
    gain_item(Role, ?package_type_bag, L).
gain_item(_, _Package, _L) ->
    skip.